package com.starryx.blog.service;

import com.starryx.blog.dao.CommentMapper;
import com.starryx.blog.po.Comment;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class CommentServiceImpl implements CommentService {

    @Autowired
    private CommentMapper commentMapper;


    @Override
    public List<Comment> listCommentByBlogId(Long blogId) {
        List<Comment> comments = commentMapper.findByBlogIdAndParentCommentNull(blogId);      // 取到顶级评论，即没有父评论的评论
        return eachComment(comments);
    }

    @Override
    @Transactional
    public int saveComment(Comment comment) {
        Long parentCommentId = comment.getParentComment().getId();          // 这是前端传来的对象中带有表单提交的 id，此时子评论和父评论还没有建立联系
        if(parentCommentId != -1){      // 当有父评论时
            comment.setParentComment(commentMapper.findOneById(parentCommentId));       // 子评论和父评论建立联系
        }else{                          // 当有没有父评论时
            comment.setParentComment(null);
        }
        comment.setCreateTime(new Date());
        return commentMapper.save(comment);
    }

    // 循环每个顶级的评论节点
    private List<Comment> eachComment(List<Comment> comments){
        // 将数据库中的顶级节点复制一份，避免对原有数据进行修改
        List<Comment> commentsView = new ArrayList<>();
        for(Comment comment : comments){
            Comment c = new Comment();
            BeanUtils.copyProperties(comment, c);
            commentsView.add(c);
        }
        // 合并评论的各层子代到第一级子代集合中
        combineChildren(commentsView);
        return commentsView;
    }

    // 存放迭代找出的所有子代的集合
    private List<Comment> tempReplys = new ArrayList<>();

    // 合并评论的各层子代到第一级子代集合中
    private void combineChildren(List<Comment> comments){
        for(Comment comment : comments){
            List<Comment> replys1 = comment.getReplyComments();
            for(Comment reply1 : replys1){      // 遍历第一层子代
                tempReplys.add(reply1);    // 第一层子节点添加到临时存放集合，考虑这里是否放了两次，如果是，将这条语句放在外面
                recursively(reply1);
            }
            // 修改顶级节点的 reply 集合为迭代处理后的集合
            comment.setReplyComments(tempReplys);
            // 清理临时存放区
            tempReplys = new ArrayList<>();
        }
    }

    private void recursively(Comment comment){
        if(comment.getReplyComments().size() > 0){      // 当其没有子节点时跳出递归
            List<Comment> replys = comment.getReplyComments();      // 获取所有子节点
            for(Comment reply : replys){            // 遍历所有子节点
                tempReplys.add(reply);          // 将所有子节点放到 tempReplys 中
                recursively(reply);
            }
        }
    }
}
